从一开始，C++就提供了按值和按引用调用，但要决定选择哪一种并不那么容易:通常按引用调用对于重要的对象来说成本更低，但更复杂。C++11添加了移动语义，现在有了不同的通过引用传递的方式:

\begin{tcolorbox}[colback=webgreen!5!white,colframe=webgreen!75!black]
\hspace*{0.75cm}常量右值引用X const\&\&也可以，但没有既定的语义。
\end{tcolorbox}

\begin{enumerate}
\item 
X const\& (常量左值引用):

参数引用传递的对象，但不能修改。

\item 
X\& (非常数的左值引用):

参数引用传递的对象，并能够修改。

\item 
X\&\& (右值引用):

参数引用传递的对象，带有移动语义，可以修改或“窃取”值。
\end{enumerate}

决定如何声明已知具体类型的参数已经够复杂的了。模板中类型是未知的，因此很难决定哪种传递机制更为合适。

第1.6.1节中，我们确实建议在函数模板中按值传递参数，除非有很好的理由:

\begin{itemize}
\item 
不能复制

\begin{tcolorbox}[colback=webgreen!5!white,colframe=webgreen!75!black]
\hspace*{0.75cm}由于C++17，即使没有可用的复制或移动构造函数，也可以通过值传递临时实体(右值)(参见B.2.1节)。因此，由于C++17的约束，不可能复制左值。
\end{tcolorbox}

\item 
参数用于返回数据。

\item 
模板只是通过保留原始参数的所有属性，将参数转发到其他地方

\item 
有显著的性能改进
\end{itemize}

本章讨论了在模板中声明参数的不同方法，提出了通过值传递参数的建议，并为不这样做的原因提供了参数。本文还讨论了在处理字符串字面值和其他数组时遇到的棘手问题。

阅读本章时，熟悉值类别(lvalue、rvalue、prvalue、xvalue等)的术语对理解本章内容会有帮助，这些在附录B中都有解释。





























